﻿using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System;

namespace FarseerPhysics.SamplesFramework
{
    [Flags]
    public enum Position
    {
        /// <summary>
        /// 站立
        /// </summary>
        Standing = 1,
        /// <summary>
        /// 下蹲
        /// </summary>
        Crouching = 2,
        /// <summary>
        /// 空中
        /// </summary>
        InAir = 3,
        /// <summary>
        /// 有一面接触墙壁
        /// </summary>
        SideAttaching = 4,
        /// <summary>
        /// 倒地
        /// </summary>
        Grounded = 5,
    }
    /// <summary>
    /// 动作姿态。可以组合。
    /// </summary>
    [Flags]
    public enum Poses
    {
        /// <summary>
        /// 站立
        /// </summary>
        Standing = 1,
        /// <summary>
        /// 下蹲
        /// </summary>
        Crouching = 2,
        /// <summary>
        /// 空中
        /// </summary>
        InAir = 4,
        /// <summary>
        /// 有一面接触墙壁
        /// </summary>
        SideAttaching = 8,
        /// <summary>
        /// 倒地
        /// </summary>
        Grounded = 16,
        /// <summary>
        /// 可自行恢复的受击硬直
        /// </summary>
        LightHit = 32,
        /// <summary>
        /// 直到倒地/受身才能取消的受击硬直
        /// </summary>
        HeavyHit = 64,
    }

    public enum PrimaryChainLevels
    {
        Basic = 0,
        A,
        B,
        C,
        D,
    }
    /// <summary>
    /// 取消链级别
    /// </summary>
    public struct ChainLevel : IComparable<ChainLevel>
    {
        public PrimaryChainLevels Primary = PrimaryChainLevels.Basic;
        public int Secondary = 0;
        public ChainLevel() { }
        public ChainLevel(PrimaryChainLevels primary, int secondary) 
        {
            Primary = primary;
            Secondary = secondary;
        }
        public int CompareTo(ChainLevel other)
        {
            int primaryResult = Primary.CompareTo(other.Primary);
            if (primaryResult == 0)
            {
                return Secondary.CompareTo(other.Secondary);
            }
            else
            {
                return primaryResult;
            }
        }
    }

    public class Actor
    {
        private Body _body;

        public Body Body
        {
            get { return _body; }
            set { _body = value; }
        }

        private IAction _currentAction;

        public IAction CurrentAction
        {
            get { return _currentAction; }
            set { _currentAction = value; }
        }

        private ActScreen _actScreen;

        public ActScreen ActScreen
        {
            get { return _actScreen; }
            set { _actScreen = value; }
        }
        
        private Sprite _sprite;
        private ActionController _actionController;

        /// <summary>
        /// 当前姿势
        /// </summary>
        private Position _position;

        public Position Position
        {
            get { return _position; }
        }


        /// <summary>
        /// 全体硬直
        /// </summary>
        private int _stopCounter;

        public int StopCounter
        {
            get { return _stopCounter; }
        }

        /// <summary>
        /// 取消链级别
        /// </summary>
        private ChainLevel _chainLevel;

        public ChainLevel ChainLevel
        {
            get { return _chainLevel; }
        }


        public Actor(ActScreen screen)
        {
            _actScreen = screen;
            _body = BodyFactory.CreateRectangle(screen.World, 5f, 5f, 1f);
            _body.BodyType = BodyType.Dynamic;
            _sprite = new Sprite(screen.ScreenManager.Assets.TextureFromShape(_body.FixtureList[0].Shape,
                                                                                MaterialType.Squares,
                                                                                Color.Orange, 1f));
            _actionController = new ActionController(this);
            _pose = Poses.Standing;
            _stopCounter = 0;
            _chainLevel = new ChainLevel(PrimaryChainLevels.Basic, 0);
        }

        public void Update()
        {
            _actionController.Update();
            // 没有任何动作的情况
            if (_actionController.IntendedAction() == ActionManager.None)
            {
            }
        }

        public void Draw()
        {
            _actScreen.ScreenManager.SpriteBatch.Begin(0, null, null, null, null, null, _actScreen.Camera.View);
            _actScreen.ScreenManager.SpriteBatch.Draw(_sprite.Texture, ConvertUnits.ToDisplayUnits(_body.Position),
                                           null,
                                           Color.White, _body.Rotation, _sprite.Origin, 1f,
                                           SpriteEffects.None, 0f);
            _actScreen.ScreenManager.SpriteBatch.End();
        }

    }

    public class ActionController
    {
        private Actor _actor;
        private ActInput _actInput;

        public ActionController(Actor actor)
        {
            _actor = actor;
            _actInput = actor.ActScreen.ActInput;
        }

        public void Update()
        {
        }

        public Action IntendedAction()
        {
            return ActionManager.None;
        }

        public void ConsumeAction()
        {
        }
    }
}